﻿using System;
using UnityConfiguration.Infrastructure;
using mpu = Microsoft.Practices.Unity;
using System.Windows.Markup;
using System.Linq;
using UnityConfiguration;
using System.Collections.Generic;

namespace UnityConfiguration
{
    /// <summary>
    /// Configuration element for storing the values of method / constructor parameters.
    /// </summary>
    [ContentProperty("Value")]
    public class Parameter : TypeResolvingObject
    {
        private InjectionParameterValue _Value;
        private string _Name;
        private string _ParameterTypeName;
        private string _GenericParameterName;

        /// <summary>
        /// Name of this parameter. Doesn't have to match the actual
        /// parameter name in the method or constructor, it's just
        /// required for uniqueness.
        /// </summary>
        public string Name {
            get { return _Name; }
            set { _Name = value; }
        }

        /// <summary>
        /// Type of this parameter.
        /// </summary>
        public string ParameterTypeName {
            get { return _ParameterTypeName; }
            set { _ParameterTypeName = value; }
        }

        /// <summary>
        /// Generic parameter name of this parameter.
        /// </summary>
        public string GenericParameterName {
            get { return _GenericParameterName; }
            set { _GenericParameterName = value; }
        }

        public IValue Value {
            get { return (IValue)_Value; }
            set { _Value = (InjectionParameterValue)value; }        
        }

        /// <summary>
        /// Get the <see cref="InjectionParameterValue"/> object for this parameter
        /// to feed to the container configuration API.
        /// </summary>
        /// <returns>The created <see cref="InjectionParameterValue"/> object.</returns>
        public mpu.InjectionParameterValue CreateInjectionParameterValue() {
            return InjectionParameterValueHelper.CreateParameterValue(
                ParameterTypeName,
                GenericParameterName,
                _Value,
                TypeResolver);
        }
    }


    /// <summary>
    /// A configuration collection of parameters for a method or constructor.
    /// </summary>
    public class ParameterCollection : TypeResolvingCollection<Parameter>
    {
        public ParameterCollection() : base() { }

        public ParameterCollection(IEnumerable<Parameter> list)
            : base(list) { 
        }
        /// <summary>
        /// Get the element with the given key.
        /// </summary>
        /// <param name="name">Key to look up</param>
        /// <returns>Element at that key.</returns>
        public Parameter this[string name] {
            get { return this.SingleOrDefault(p => p.Name == name); }
        }

    }
}
